﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Data.Linq.SqlClient;

namespace MyLinqHelper
{
    public class Criterion
    {
        private Comparision comparision;
        public object LeftOperand { get; set; }
        public object RghtOperand { get; set; }
        public object OtherOperand { get; set; }
        public Comparision Comparision { get { return this.comparision; } }

        public Criterion(Comparision comparision, object leftOperand, object rightOperand)
        {
            this.comparision = comparision;
            this.LeftOperand = leftOperand;
            this.RghtOperand = rightOperand;
        }

        public Criterion(Comparision comparision, object leftOperand, object rightOperand, object otherOperand)
            : this(comparision, leftOperand, rightOperand)
        {
            this.OtherOperand = otherOperand;
        }

        internal Expression GetExpression<TEntity>(ParameterExpression pe)
        {
            Expression left = Expression.Property(pe, typeof(TEntity).GetProperty(this.LeftOperand.ToString()));
            Expression right = Expression.Constant(this.RghtOperand, typeof(TEntity).GetProperty(this.LeftOperand.ToString()).PropertyType);
            switch (this.Comparision)
            {
                case Comparision.Equal:
                    return Expression.Equal(left, right);
                case Comparision.LessThan:
                    return Expression.LessThan(left, right);
                case Comparision.LessThanOrEqual:
                    return Expression.LessThanOrEqual(left, right);
                case Comparision.GreaterThan:
                    return Expression.GreaterThan(left, right);
                case Comparision.GreaterThanOrEqual:
                    return Expression.GreaterThanOrEqual(left, right);
                case Comparision.Like:
                    left = Expression.Call(typeof(SqlMethods).GetMethod("Like"), new Expression[] { left, right});
                    right = Expression.Constant(true, typeof(bool));
                    return Expression.Equal(left, right);
                case Comparision.In:
                    return null;
                case Comparision.Between:
                    Expression other = Expression.Constant(this.OtherOperand, typeof(TEntity).GetProperty(this.LeftOperand.ToString()).PropertyType);
                    Expression e1 = Expression.LessThanOrEqual(left, right);
                    Expression e2 = Expression.GreaterThanOrEqual(left, other);
                    return Expression.And(e1, e2);
                 
            }
            return null;
        }
    }
}
